#include "Common.h"
#include "Root.h"
#include "SceneManager.h"
#include "Render.h"
#include "RenderWindow.h"
#include "MaterialManager.h"
#include "SkeletonManager.h"
#include "MeshManager.h"
#include "InputManager.h"
#include "Engine.h"
#include "Timer.h"
#include "UIManager.h"
#include "NetworkManager.h"
#include "PhysicsSystem.h"
#include <windows.h>

//------------------------------------------
Root::Root()
	: mRenderWindow(NULL)
{
}
//------------------------------------------
Root::~Root()
{
	if (mRenderWindow) delete mRenderWindow;

	Physics::System::DeleteInstance();
	UIManager::DeleteInstance();
	NetworkManager::DeleteInstance();
	InputManager::DeleteInstance();
	MeshManager::DeleteInstance();
	SkeletonManager::DeleteInstance();
	MaterialManager::DeleteInstance();
	Render::DeleteInstance();
	Timer::DeleteInstance();
}
//------------------------------------------
bool Root::Init()
{
	Timer::NewInstance();

	mRenderWindow = new RenderWindow();
	if (!mRenderWindow->Init())
		return false;

	// init the render.
	Render::NewInstance();
	if (!Render::Instance().Init(mRenderWindow->getWnd()))
		return false;

	mRenderWindow->OnRenderInited();

	MaterialManager::NewInstance();
	MaterialManager::Instance().BuildReserveMaterial();

	SkeletonManager::NewInstance();

	MeshManager::NewInstance();
	MeshManager::Instance().BuildShapeMeshes();

	InputManager::NewInstance();
	if (!InputManager::Instance().Init(mRenderWindow->getWnd()))
		return false;

	NetworkManager::NewInstance();
	if (!NetworkManager::Instance().Init())
		return false;

	UIManager::NewInstance();
	if (!UIManager::Instance().Init())
		return false;

	InputManager::Instance().AddListener(&UIManager::Instance());

	Physics::System::NewInstance();
	if (!Physics::System::Instance().Init())
		return false;

	return true;
}
//------------------------------------------
void Root::Start()
{
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    // Enter the message loop
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE))
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
            Tick();
    }
}
//------------------------------------------
void Root::Exit()
{
	Render::Instance().Exit();

	NetworkManager::Instance().Destroy();

	if (mRenderWindow)
		mRenderWindow->Exit();
}
//------------------------------------------
SceneManager* Root::CreateSceneManager(const std::string& name)
{
	return new SceneManager(name);
}
//------------------------------------------
void Root::DestroySceneManager(SceneManager* sceneMgr)
{
	delete sceneMgr;
}
//------------------------------------------
void Root::Tick()
{
	float elapsedTime = Timer::Instance().GetElapsedTime();

	InputManager::Instance().Update(elapsedTime);

	NetworkManager::Instance().Update(elapsedTime);

	Physics::System::Instance().Update(elapsedTime);

	Engine::Instance().Update(elapsedTime);

	RenderOneFrame(elapsedTime);
}
//------------------------------------------
void Root::RenderOneFrame(float elapsedTime)
{
	LPDIRECT3DDEVICE9 device = Render::Instance().getDevice();
	VERIFY_D3D(device->BeginScene());

	if (mRenderWindow != NULL)
		mRenderWindow->Update();

	UIManager::Instance().Render(elapsedTime);

	VERIFY_D3D(device->EndScene());
	VERIFY_D3D(device->Present(NULL,NULL,NULL,NULL));
}
//------------------------------------------
void Root::OnWindowResized(int widht, int height)
{
	if (mRenderWindow != NULL)
		mRenderWindow->OnWindowResized(widht, height);
}
//------------------------------------------